<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>OpenLayers 点线面示例</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ol@v7.4.0/ol.css">
    <script src="https://cdn.jsdelivr.net/npm/ol@v7.4.0/dist/ol.js"></script>
    <style>
        html, body {
            margin: 0;
            padding: 0;
            width: 100%;
            height: 100%;
            overflow: hidden;
        }
        
        .map {
            position: absolute;
            top: 0;
            bottom: 0;
            left: 0;
            right: 0;
            width: 100%;
            height: 100%;
        }
        
        .legend {
            position: absolute;
            top: 10px;
            right: 10px;
            background: white;
            padding: 10px;
            border-radius: 4px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
            z-index: 1000;
        }

        .legend-item {
            display: flex;
            align-items: center;
            margin: 5px 0;
        }

        .legend-color {
            width: 20px;
            height: 20px;
            margin-right: 8px;
            border-radius: 3px;
        }

        .coordinates {
            position: absolute;
            bottom: 10px;
            right: 10px;
            background: rgba(255,255,255,0.8);
            padding: 5px 10px;
            border-radius: 4px;
            font-size: 12px;
            z-index: 1000;
        }

        /* 添加弹窗样式 */
        .ol-popup {
            position: absolute;
            background-color: white;
            box-shadow: 0 1px 4px rgba(0,0,0,0.2);
            padding: 15px;
            border-radius: 10px;
            border: 1px solid #cccccc;
            bottom: 12px;
            left: -50px;
            min-width: 200px;
            z-index: 1000;
        }

        .ol-popup:after, .ol-popup:before {
            top: 100%;
            border: solid transparent;
            content: " ";
            height: 0;
            width: 0;
            position: absolute;
            pointer-events: none;
        }

        .ol-popup:after {
            border-top-color: white;
            border-width: 10px;
            left: 48px;
            margin-left: -10px;
        }

        .ol-popup:before {
            border-top-color: #cccccc;
            border-width: 11px;
            left: 48px;
            margin-left: -11px;
        }

        .ol-popup-closer {
            text-decoration: none;
            position: absolute;
            top: 2px;
            right: 8px;
            color: #999;
            font-size: 16px;
        }

        .ol-popup-closer:hover {
            color: #666;
        }

        .popup-content {
            margin-top: 10px;
        }

        .popup-title {
            font-weight: bold;
            margin-bottom: 5px;
            color: #409EFF;
        }

        .popup-info {
            font-size: 13px;
            color: #666;
            line-height: 1.4;
        }
    </style>
</head>
<body>
    <div id="map" class="map"></div>
    
    <!-- 添加弹窗容器 -->
    <div id="popup" class="ol-popup">
        <a href="#" id="popup-closer" class="ol-popup-closer">×</a>
        <div id="popup-content"></div>
    </div>

    <!-- 图例 -->
    <div class="legend">
        <div class="legend-item">
            <div class="legend-color" style="background: #409EFF"></div>
            <span>重要地点</span>
        </div>
        <div class="legend-item">
            <div class="legend-color" style="background: #67C23A"></div>
            <span>路线</span>
        </div>
        <div class="legend-item">
            <div class="legend-color" style="background: rgba(230,162,60,0.4)"></div>
            <span>区域</span>
        </div>
    </div>

    <!-- 坐标显示 -->
    <div id="coordinates" class="coordinates"></div>

    <script>
        // 示例数据增加更多信息
        const pointsData = [
            { 
                name: '天安门', 
                coordinates: [116.397428, 39.90923],
                info: {
                    address: '北京市东城区长安街',
                    description: '中华人民共和国的国家象征',
                    visitTime: '全天开放'
                }
            },
            { 
                name: '北京站', 
                coordinates: [116.427028, 39.902802],
                info: {
                    address: '北京市东城区毛家湾胡同甲13号',
                    description: '北京重要的交通枢纽',
                    visitTime: '24小时运营'
                }
            },
            { 
                name: '王府井', 
                coordinates: [116.418261, 39.915474],
                info: {
                    address: '北京市东城区王府井大街',
                    description: '著名的商业街区',
                    visitTime: '商场10:00-22:00'
                }
            }
        ];

        const lineData = [
            [116.397428, 39.90923],  // 天安门
            [116.418261, 39.915474], // 王府井
            [116.427028, 39.902802]  // 北京站
        ];

        const polygonData = [
            [
                [116.390, 39.915],
                [116.430, 39.915],
                [116.430, 39.895],
                [116.390, 39.895],
                [116.390, 39.915]
            ]
        ];

        // 创建矢量图层和数据源
        const vectorSource = new ol.source.Vector();

        // 添加点要素时包含额外信息
        pointsData.forEach(point => {
            const feature = new ol.Feature({
                geometry: new ol.geom.Point(
                    ol.proj.fromLonLat(point.coordinates)
                ),
                name: point.name,
                info: point.info
            });
            vectorSource.addFeature(feature);
        });

        // 添加线要素
        const lineFeature = new ol.Feature({
            geometry: new ol.geom.LineString(
                lineData.map(coord => ol.proj.fromLonLat(coord))
            )
        });
        vectorSource.addFeature(lineFeature);

        // 添加面要素
        const polygonFeature = new ol.Feature({
            geometry: new ol.geom.Polygon([
                polygonData[0].map(coord => ol.proj.fromLonLat(coord))
            ])
        });
        vectorSource.addFeature(polygonFeature);

        // 创建样式
        const styles = {
            point: new ol.style.Style({
                image: new ol.style.Circle({
                    radius: 7,
                    fill: new ol.style.Fill({
                        color: '#409EFF'
                    }),
                    stroke: new ol.style.Stroke({
                        color: '#fff',
                        width: 2
                    })
                }),
                text: new ol.style.Text({
                    font: '12px sans-serif',
                    fill: new ol.style.Fill({ color: '#333' }),
                    stroke: new ol.style.Stroke({
                        color: '#fff',
                        width: 3
                    }),
                    offsetY: -15
                })
            }),
            line: new ol.style.Style({
                stroke: new ol.style.Stroke({
                    color: '#67C23A',
                    width: 3
                })
            }),
            polygon: new ol.style.Style({
                fill: new ol.style.Fill({
                    color: 'rgba(230,162,60,0.4)'
                }),
                stroke: new ol.style.Stroke({
                    color: '#E6A23C',
                    width: 2
                })
            })
        };

        // 矢量图层
        const vectorLayer = new ol.layer.Vector({
            source: vectorSource,
            style: function(feature) {
                const geometry = feature.getGeometry();
                if (geometry instanceof ol.geom.Point) {
                    styles.point.getText().setText(feature.get('name'));
                    return styles.point;
                } else if (geometry instanceof ol.geom.LineString) {
                    return styles.line;
                } else if (geometry instanceof ol.geom.Polygon) {
                    return styles.polygon;
                }
            }
        });

        // 创建弹窗
        const container = document.getElementById('popup');
        const content = document.getElementById('popup-content');
        const closer = document.getElementById('popup-closer');

        const overlay = new ol.Overlay({
            element: container,
            autoPan: true,
            autoPanAnimation: {
                duration: 250
            }
        });

        // 关闭弹窗
        closer.onclick = function() {
            overlay.setPosition(undefined);
            closer.blur();
            return false;
        };

        // 创建地图时添加弹窗图层
        const map = new ol.Map({
            target: 'map',
            overlays: [overlay],  // 添加弹窗图层
            layers: [
                new ol.layer.Tile({
                    source: new ol.source.XYZ({
                        url: 'https://webst0{1-4}.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}',
                        crossOrigin: 'anonymous'
                    })
                }),
                vectorLayer
            ],
            view: new ol.View({
                center: ol.proj.fromLonLat([116.397428, 39.90923]),
                zoom: 14
            })
        });

        // 添加点击事件处理
        map.on('click', function(evt) {
            const feature = map.forEachFeatureAtPixel(evt.pixel, function(feature) {
                return feature;
            });

            if (feature && feature.getGeometry() instanceof ol.geom.Point) {
                const coordinates = feature.getGeometry().getCoordinates();
                const name = feature.get('name');
                const info = feature.get('info');

                // 构建弹窗内容
                content.innerHTML = `
                    <div class="popup-title">${name}</div>
                    <div class="popup-content">
                        <div class="popup-info">
                            <p><strong>地址：</strong>${info.address}</p>
                            <p><strong>简介：</strong>${info.description}</p>
                            <p><strong>开放时间：</strong>${info.visitTime}</p>
                        </div>
                    </div>
                `;

                overlay.setPosition(coordinates);
            }
        });

        // 鼠标样式处理
        map.on('pointermove', function(e) {
            const pixel = map.getEventPixel(e.originalEvent);
            const hit = map.hasFeatureAtPixel(pixel);
            map.getTarget().style.cursor = hit ? 'pointer' : '';
        });

        // 鼠标移动显示坐标
        map.on('pointermove', function(evt) {
            const coords = ol.proj.transform(evt.coordinate, 'EPSG:3857', 'EPSG:4326');
            document.getElementById('coordinates').innerHTML = 
                `经度: ${coords[0].toFixed(6)}, 纬度: ${coords[1].toFixed(6)}`;
        });
    </script>
</body>
</html> 